package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.WmNewsMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wmchannel.pojos.WmChannel;
import com.heima.model.wmnews.dtos.WmNewsDto;
import com.heima.model.wmnews.dtos.WmNewsPageReqDto;
import com.heima.model.wmnews.dtos.WmNewsStatusDto;
import com.heima.model.wmnews.pojos.WmNews;
import com.heima.model.wmnews.pojos.WmNewsMaterial;
import com.heima.utils.common.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;
    @Autowired
    private WmNewsMaterialService wmNewsMaterialService;
    @Autowired
    private WmNewsAutoScanService wmNewsAutoScanService;
    @Autowired
    private WmNewsTaskService wmNewsTaskService;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 上架下架
     *
     * @param wmNewsStatusDto
     */
    @Override
    public ResponseResult downOrUp(WmNewsStatusDto wmNewsStatusDto) {
        if(wmNewsStatusDto.getId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews news = this.getById(wmNewsStatusDto.getId());
        if(news == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }
        // 修改文章状态
        if (wmNewsStatusDto.getEnable() != null && wmNewsStatusDto.getEnable()>-1 && wmNewsStatusDto.getEnable()<2){
            boolean update = this.update(Wrappers.<WmNews>lambdaUpdate().set(
                    WmNews::getEnable, wmNewsStatusDto.getEnable()
            ).eq(WmNews::getId, wmNewsStatusDto.getId()));
            if(update){
                // 发送消息给kafka
                Map<String, Object> map = new HashMap<>();
                map.put("articleId",news.getArticleId());
                map.put("enable",wmNewsStatusDto.getEnable());
                // 添加消息到kafka,消息内容需要转为字符串
                kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JSON.toJSONString(map));

                return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
            }
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.ERROR);
    }

    @Override
    public ResponseResult getList(WmNewsPageReqDto dto) {
        if(dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        // 获取用户id
        Integer userId = WmThreadLocalUtil.getUser().getId();
        if(userId == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        Page page = new Page(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        //状态
        queryWrapper.eq(dto.getStatus() != null, WmNews::getStatus,dto.getStatus());
        //频道
        queryWrapper.eq(dto.getChannelId() != null, WmNews::getChannelId,dto.getChannelId());
        //关键字 keyword
        queryWrapper.eq(StringUtils.isNotBlank(dto.getKeyword()), WmNews::getChannelId,dto.getKeyword());
        // 时间
        if(dto.getBeginPubdate() != null && dto.getEndPubdate() != null){
            queryWrapper.between(WmNews::getPublishTime, dto.getBeginPubdate(), dto.getEndPubdate());
        }
        // 排序
        queryWrapper.orderByDesc(WmNews::getCreatedTime);
        page = page(page, queryWrapper);
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        pageResponseResult.setData(page.getRecords());
        return pageResponseResult;
    }

    /**
     * 提交文章
     * @param dto
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        if(dto.getContent() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getType() == -1){
            dto.setType(null);
        }
        // 新增
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        List<String> images = dto.getImages();
        if(images!=null){
            String imageStr = StringUtils.join(images, ",");
            wmNews.setImages(imageStr);
        }
        // 执行修改和保存
        boolean save = this.saveOrUpdateNews(wmNews);
        // 如果是草稿
        if(dto.getStatus() == 0){
            return ResponseResult.okResult(null);
        }
        // 新增或者修改成功了
        if(save){
            List list = this.drowOutImg(wmNews); // 抽取图片
            //4.1 内容中图片与文章的关系
            contentImageToNews(wmNews, list, (short) 0);
            //4.2 封面图片与文章的关系
            fengmianImageToNews(wmNews,dto,list,(short)1);
        }

//        wmNewsAutoScanService.autoScanWmNews(wmNews.getId()); // 异步调用自动审核
        wmNewsTaskService.addNewsToTask(wmNews.getId(), wmNews.getPublishTime()); // 添加到任务队列redis中


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 修改文章图片信息
     * @param wmNews
     * @param dto
     * @param imageList
     * @param type
     */
    private void fengmianImageToNews(WmNews wmNews,WmNewsDto dto,List imageList, short type) {
        //1.获取封面图片
        List<String> images = dto.getImages();
        //自动
        if(dto.getType()==null){
            if(imageList.size()>=1 && imageList.size()<3){
                //取出第一张图片作为封面
                images= (List<String>) imageList.stream().limit(1).collect(Collectors.toList());
                //单图设置类型
                wmNews.setType((short) 1);
            }else if(imageList.size()>=3){
                images= (List<String>) imageList.stream().limit(3).collect(Collectors.toList());
                //多图设置类型
                wmNews.setType((short) 3);
            }else{
                wmNews.setType((short) 0);
            }

            wmNews.setImages(StringUtils.join(images, ","));
            updateById(wmNews);
        }
        //否则，直接插入到中间表中
        saveNewsMaterial(wmNews, type, images);
    }

    /**
     *
     * @param wmNews
     * @param imageList
     * @param type
     */
    private void contentImageToNews(WmNews wmNews, List<String> imageList, Short type) {
        saveNewsMaterial(wmNews, type, imageList);
    }

    private void saveNewsMaterial(WmNews wmNews, Short type, List<String> imageList){
        if(imageList != null && imageList.size()>0){
            // 根据图片地址查询素材id
            List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(
                    Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, imageList)
            );
            // 获取素材id
            List<Integer> collect = wmMaterials.stream().map(
                    WmMaterial::getId
            ).collect(Collectors.toList());
            WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
//            List<WmNewsMaterial> wmNewsMaterialList;
            List<WmNewsMaterial> list = collect.stream().map(col -> {
                wmNewsMaterial.setMaterialId(col);
                wmNewsMaterial.setNewsId(wmNews.getId());
                wmNewsMaterial.setType(type);
                wmNewsMaterial.setOrd((short) 0);
                return wmNewsMaterial;
            }).collect(Collectors.toList());
            wmNewsMaterialService.saveBatch(list);
        }
    }

    private boolean saveOrUpdateNews(WmNews wmNews){
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
        // 判断是新增还是修改
        boolean save = false;
        if(wmNews.getId() == null){
            save = save(wmNews);
        }else{
            // 删除中间表
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,wmNews.getId()));
            // 修改文章
            save = updateById(wmNews);
        }
        return save;
    }
    /**
     * 获取所有图片信息
     */
    private List drowOutImg(WmNews wmNews){
        List imgList = new ArrayList<>();
        String content = wmNews.getContent();
        List<Map> mapList = JSON.parseArray(content, Map.class);
        for (Map map : mapList) {
            if(map.get("type").equals("image")){
                imgList.add((String) map.get("value"));
            }
        }
        return imgList;
    }
}
